package org.dark.fund.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.dark.fund.api.AccessTokenService;
import org.dark.fund.api.ITokenService;
import org.dark.fund.api.model.AccessToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

import static org.dark.fund.consts.FundSysConsts.TOKEN_HEADER;

/**
 * 对登陆进行验证
 *
 * @author mashu
 */

@Slf4j
@Component
public class LoginFilter implements HandlerInterceptor, ITokenService {

    private static ThreadLocal<AccessToken> tokenThreadLocal = new ThreadLocal<>();

    @Value("${mock.test}")
    private boolean skip;

    /**
     * 系统组件跳过
     */
    protected static List<String> SYSTEM_SKIP_LOGINS = new ArrayList<>();

    /**
     * 业务跳过
     */
    protected static List<String> MANUAL_SKIP_LOGINS = new ArrayList<>();

    protected static List<String> SKIP_LOGINS = new ArrayList<>();

    static {
        MANUAL_SKIP_LOGINS.add("logout");
        MANUAL_SKIP_LOGINS.add("login");
        MANUAL_SKIP_LOGINS.add("/user/register");
        MANUAL_SKIP_LOGINS.add("/fund/query");
        SYSTEM_SKIP_LOGINS.add("actuator");
        SYSTEM_SKIP_LOGINS.add("api-docs");
        SYSTEM_SKIP_LOGINS.add("swagger");

        SKIP_LOGINS.addAll(MANUAL_SKIP_LOGINS);
        SKIP_LOGINS.addAll(SYSTEM_SKIP_LOGINS);
    }
    @Autowired
    AccessTokenService accessTokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (skip) {
            return true;
        }

        String path = request.getServletPath();
        for (String skipPath : SKIP_LOGINS) {
            if (path.contains(skipPath)) {
                return true;
            }
        }
        String token = request.getHeader(TOKEN_HEADER);
        // 检查token, 是否登陆/登陆是否超时
        AccessToken accessToken = accessTokenService.touchToken(token);
        tokenThreadLocal.set(accessToken);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        tokenThreadLocal.remove();
    }


    @Override
    public AccessToken get() {
        return tokenThreadLocal.get();
    }
}
